﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ERP.ERPSystem.ProductionSystem.Dto;
using ERP.Team.ProductionSystem;
using ERP.Team.RBAC;
using ERP.Common.Results;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Application.Dtos;

namespace ERP.ERPSystem.ProductionSystem
{
    public class ProductionWorkOrderMainService : ApplicationService, IProductionWorkOrderMainServices
    {
        private readonly IRepository<ProductionWorkOrderMain, int> _productionServices;

        public ProductionWorkOrderMainService(IRepository<ProductionWorkOrderMain, int> productionrepository)
        {
            _productionServices = productionrepository;
        }

        /// <summary>
        /// 添加生产工单
        /// </summary>
        /// <param name="productionWorkOrderMainDto"></param>
        /// <returns></returns>
        public async Task<int> AddProductionWorkOrder(ProductionWorkOrderDto productionWorkOrderMainDto)
        {
            try
            {
                var productionWork = ObjectMapper.Map<ProductionWorkOrderDto, ProductionWorkOrderMain>(productionWorkOrderMainDto);
                var result = await _productionServices.InsertAsync(productionWork);
                return result.Id;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException("添加生产工单失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 显示生产工单
        /// </summary>
        /// <returns></returns>
        public async Task<List<ProductionWorkOrderMain>> GetProductionWorkOrder(
            string workOrderCode = "",
            string workOrderName = "",
            string sourceOrder = "",
            string workOrderType = "",
            string productCode = "",
            string productName = "",
            string customerCode = "",
            string customerName = "",
            string demandDate = "")
        {
            var query = await _productionServices.GetQueryableAsync();

            // 应用搜索条件
            if (!string.IsNullOrWhiteSpace(workOrderCode))
                query = query.Where(x => x.WorkOrderCode.Contains(workOrderCode));

            if (!string.IsNullOrWhiteSpace(workOrderName))
                query = query.Where(x => x.WorkOrderName.Contains(workOrderName));

            if (!string.IsNullOrWhiteSpace(sourceOrder))
                query = query.Where(x => x.SourceType == sourceOrder);

            if (!string.IsNullOrWhiteSpace(workOrderType))
                query = query.Where(x => x.WorkOrderType == workOrderType);

            if (!string.IsNullOrWhiteSpace(productCode))
                query = query.Where(x => x.ProductCode.Contains(productCode));

            if (!string.IsNullOrWhiteSpace(productName))
                query = query.Where(x => x.ProductName.Contains(productName));

            if (!string.IsNullOrWhiteSpace(customerCode))
                query = query.Where(x => x.CustomerCode.Contains(customerCode));

            if (!string.IsNullOrWhiteSpace(customerName))
                query = query.Where(x => x.CustomerName.Contains(customerName));

            if (!string.IsNullOrWhiteSpace(demandDate))
            {
                if (DateTime.TryParse(demandDate, out DateTime date))
                {
                    query = query.Where(x => x.DemandDate.Date == date.Date);
                }
            }

            return await AsyncExecuter.ToListAsync(query);
        }

        /// <summary>
        /// 分页查询生产工单
        /// </summary>
        /// <param name="skipCount"></param>
        /// <param name="maxResultCount"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ProductionWorkOrderMain>> GetPagedProductionWorkOrder(int skipCount, int maxResultCount)
        {
            var query = await _productionServices.GetQueryableAsync();
            var totalCount = await AsyncExecuter.CountAsync(query);
            var items = await AsyncExecuter.ToListAsync(query.Skip(skipCount).Take(maxResultCount));

            return new PagedResultDto<ProductionWorkOrderMain>
            {
                TotalCount = totalCount,
                Items = items
            };
        }

        /// <summary>
        /// 更新生产工单
        /// </summary>
        /// <param name="productionWorkOrderMainDto"></param>
        /// <returns></returns>
        public async Task<int> UpdateProductionWorkOrder(ProductionWorkOrderDto productionWorkOrderMainDto)
        {
            try
            {
                var existingOrder = await _productionServices.GetAsync(productionWorkOrderMainDto.Id);
                if (existingOrder == null)
                {
                    throw new UserFriendlyException("未找到指定的生产工单");
                }

                ObjectMapper.Map(productionWorkOrderMainDto, existingOrder);
                await _productionServices.UpdateAsync(existingOrder);
                return existingOrder.Id;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException("更新生产工单失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 删除生产工单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteProductionWorkOrder(int id)
        {
            try
            {
                await _productionServices.DeleteAsync(id);
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException("删除生产工单失败：" + ex.Message);
            }
        }

        /// <summary>
        /// 修改生产工单
        /// </summary>
        /// <returns></returns>
        public async Task<bool> UpdateWorkOrder(ProductionWorkOrderMain model)
        {
            try
            {
                var entity = await _productionServices.FindAsync(x => x.Id == model.Id);
                if (entity == null)
                {
                    return false;
                }

                entity.WorkOrderCode = model.WorkOrderCode;
                entity.WorkOrderName = model.WorkOrderName;
                entity.SourceType = model.SourceType;
                entity.DocumentStatus = model.DocumentStatus;
                entity.WorkOrderType = model.WorkOrderType;
                entity.ProductCode = model.ProductCode;
                entity.ProductName = model.ProductName;
                entity.ProductModel = model.ProductModel;
                entity.Unit = model.Unit;
                entity.WorkOrderQuantity = model.WorkOrderQuantity;
                entity.DemandDate = model.DemandDate;
                entity.BatchNo = model.BatchNo;
                entity.Remark = model.Remark;
                entity.CustomerCode = model.CustomerCode;
                entity.CustomerName = model.CustomerName;
                entity.OrderCode = model.OrderCode;

                await _productionServices.UpdateAsync(entity);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 根据ID获取生产工单
        /// </summary>
        /// <param name="id">工单ID</param>
        /// <returns></returns>
        public async Task<ProductionWorkOrderMain> GetAsync(int id)
        {
            return await _productionServices.GetAsync(id);
        }

        /// <summary>
        /// 获取甘特图数据
        /// </summary>
        /// <param name="queryDto">查询条件</param>
        /// <returns>甘特图数据</returns>
        public async Task<APIPaging<ProductionWorkOrderGanttDto>> GetGanttData(ProductionWorkOrderGanttQueryDto queryDto)
        {
            try
            {
                var pageList = new APIPaging<ProductionWorkOrderGanttDto>();
                var query = await _productionServices.GetQueryableAsync();

                // 筛选条件
                if (!string.IsNullOrEmpty(queryDto.WorkOrderCode))
                {
                    query = query.Where(x => x.WorkOrderCode.Contains(queryDto.WorkOrderCode));
                }

                if (!string.IsNullOrEmpty(queryDto.WorkOrderName))
                {
                    query = query.Where(x => x.WorkOrderName.Contains(queryDto.WorkOrderName));
                }

                if (!string.IsNullOrEmpty(queryDto.ProductCode))
                {
                    query = query.Where(x => x.ProductCode.Contains(queryDto.ProductCode));
                }

                if (!string.IsNullOrEmpty(queryDto.ProductName))
                {
                    query = query.Where(x => x.ProductName.Contains(queryDto.ProductName));
                }

                if (!string.IsNullOrEmpty(queryDto.CustomerCode))
                {
                    query = query.Where(x => x.CustomerCode.Contains(queryDto.CustomerCode));
                }

                if (!string.IsNullOrEmpty(queryDto.CustomerName))
                {
                    query = query.Where(x => x.CustomerName.Contains(queryDto.CustomerName));
                }

                // 需求日期范围筛选
                if (queryDto.DemandDateStart.HasValue)
                {
                    query = query.Where(x => x.DemandDate >= queryDto.DemandDateStart.Value);
                }

                if (queryDto.DemandDateEnd.HasValue)
                {
                    var endDate = queryDto.DemandDateEnd.Value.Date.AddDays(1);
                    query = query.Where(x => x.DemandDate < endDate);
                }

                // 列表页只显示状态为1（已确认）的数据  
                // 注意：数据库中DocumentStatus=1代表已确认状态，前端会将其映射为状态2显示
                query = query.Where(x => x.DocumentStatus == 1);

                // 计算总数
                pageList.PageCount = query.Count();

                // 分页和排序
                var workOrders = query
                    .OrderBy(x => x.DemandDate)
                    .ThenBy(x => x.WorkOrderCode)
                    .Skip((queryDto.Page - 1) * queryDto.Limit)
                    .Take(queryDto.Limit)
                    .ToList();

                // 转换为甘特图DTO
                pageList.ListDate = workOrders.Select(ConvertToGanttDto).ToList();

                // 计算总页数
                pageList.PageIndex = Convert.ToInt32(Math.Ceiling(pageList.PageCount * 1.0 / queryDto.Limit));

                return pageList;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException($"获取甘特图数据失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取甘特图时间范围内的工单数据
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>工单数据列表</returns>
        public async Task<List<ProductionWorkOrderGanttDto>> GetGanttDataByTimeRange(DateTime startTime, DateTime endTime)
        {
            try
            {
                var query = await _productionServices.GetQueryableAsync();

                // 筛选时间范围内的工单
                query = query.Where(x => x.DemandDate >= startTime && x.DemandDate <= endTime);
                
                // 只显示状态为1（已确认）的数据
                query = query.Where(x => x.DocumentStatus == 1);

                var workOrders = await AsyncExecuter.ToListAsync(
                    query.OrderBy(x => x.DemandDate).ThenBy(x => x.WorkOrderCode)
                );

                return workOrders.Select(ConvertToGanttDto).ToList();
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException($"获取时间范围甘特图数据失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新工单生产进度
        /// </summary>
        /// <param name="workOrderId">工单ID</param>
        /// <param name="progressPercent">进度百分比</param>
        /// <param name="completedQuantity">已完成数量</param>
        /// <returns>更新结果</returns>
        public async Task<bool> UpdateProductionProgress(int workOrderId, decimal progressPercent, int completedQuantity)
        {
            try
            {
                var workOrder = await _productionServices.FirstOrDefaultAsync(x => x.Id == workOrderId);
                if (workOrder == null)
                {
                    throw new UserFriendlyException($"工单ID {workOrderId} 不存在");
                }

                // 注意：ProductionWorkOrderMain实体没有进度字段，这里只是演示
                // 实际应用中可能需要扩展实体或创建关联表存储进度信息
                
                await _productionServices.UpdateAsync(workOrder);
                return true;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException($"更新生产进度失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新工单生产状态
        /// </summary>
        /// <param name="workOrderId">工单ID</param>
        /// <param name="status">状态：0-草稿 1-已确认 2-已完成 3-暂停 4-异常</param>
        /// <returns>更新结果</returns>
        public async Task<bool> UpdateProductionStatus(int workOrderId, int status)
        {
            try
            {
                var workOrder = await _productionServices.FirstOrDefaultAsync(x => x.Id == workOrderId);
                if (workOrder == null)
                {
                    throw new UserFriendlyException($"工单ID {workOrderId} 不存在");
                }

                // 使用DocumentStatus字段来存储生产状态
                workOrder.DocumentStatus = status;
                
                await _productionServices.UpdateAsync(workOrder);
                return true;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException($"更新生产状态失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 将ProductionWorkOrderMain转换为甘特图DTO
        /// </summary>
        /// <param name="workOrder">工单实体</param>
        /// <returns>甘特图DTO</returns>
        private ProductionWorkOrderGanttDto ConvertToGanttDto(ProductionWorkOrderMain workOrder)
        {
            // 根据DocumentStatus生成状态文本
            string statusText = workOrder.DocumentStatus switch
            {
                0 => "草稿",
                1 => "已确认",
                2 => "已完成",
                3 => "暂停",
                4 => "异常",
                _ => "未知"
            };

            // 计算进度百分比（示例逻辑）
            decimal progressPercent = workOrder.DocumentStatus switch
            {
                0 => 0,
                1 => 50, // 已确认默认50%
                2 => 100,
                _ => 0
            };

            return new ProductionWorkOrderGanttDto
            {
                Id = workOrder.Id,
                WorkOrderCode = workOrder.WorkOrderCode ?? "",
                WorkOrderName = workOrder.WorkOrderName ?? "",
                ProductCode = workOrder.ProductCode ?? "",
                ProductName = workOrder.ProductName ?? "",
                ProductModel = workOrder.ProductModel ?? "",
                Unit = workOrder.Unit ?? "",
                WorkOrderQuantity = workOrder.WorkOrderQuantity,
                DemandDate = workOrder.DemandDate,
                
                // 计划时间（使用需求日期作为基准）
                PlannedStartTime = workOrder.DemandDate.AddDays(-7), // 默认提前7天开始
                PlannedEndTime = workOrder.DemandDate,
                
                // 实际时间（根据状态设置）
                ActualStartTime = workOrder.DocumentStatus >= 1 ? workOrder.DemandDate.AddDays(-5) : null,
                ActualEndTime = workOrder.DocumentStatus == 2 ? workOrder.DemandDate : null,
                
                ProgressPercent = progressPercent,
                ProductionStatus = workOrder.DocumentStatus,
                ProductionStatusText = statusText,
                CustomerCode = workOrder.CustomerCode ?? "",
                CustomerName = workOrder.CustomerName ?? "",
                
                // 已生产数量（根据进度计算）
                CompletedQuantity = (int)(workOrder.WorkOrderQuantity * progressPercent / 100),
                
                ProcessInfo = "主工序", // 默认值
                Priority = 1 // 默认优先级
            };
        }

        // ------------------------------------
        /// <summary>
        /// 查询工单
        /// </summary>
        /// <returns>返回数据</returns>
        public async Task<List<ProductionWorkOrderMain>> QueryWorkOrder()
        {
            var info = await _productionServices.GetListAsync();
            return info;
        }
    }
}
